package com.emeraude;

import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;

import javax.swing.JFrame;

public class Game extends Canvas
{

  /**
   * 
   */
  private static final long       serialVersionUID = 7494761812280052499L;
  private final BufferStrategy    strategy;
  private final boolean           gameRunning      = true;
  private final ArrayList<Entity> entities         = new ArrayList<Entity>();
  private final PlayerEntity      player;
  //private final WallEntity        wall;
  private boolean                 leftPressed;
  public boolean                  battleInProgess;

  private boolean                 rightPressed;
  private boolean                 upPressed;
  private boolean                 downPressed;
  private final WorldMap          map;
  private final MyFrame           container;

  //private final JPanel            panel;

  public Game()
  {
    //final JFrame container = new JFrame("Test");
    //container = new JFrame("Test");
    container = new MyFrame();
    //panel = (JPanel)container.getContentPane();
    //panel.setPreferredSize(new Dimension(WorldMap.TILD_WIDTH * WorldMap.NB_TILD_ON_SCREEN, WorldMap.TILD_HEIGHT * WorldMap.NB_TILD_ON_SCREEN));
    //panel.setPreferredSize(new Dimension(800, 800));
    //panel.setLayout(null);
    //container.setPreferredSize(new Dimension(WorldMap.TILD_WIDTH * WorldMap.NB_TILD_ON_SCREEN, WorldMap.TILD_HEIGHT * WorldMap.NB_TILD_ON_SCREEN));
    container.setLayout(null);
    container.setSize(400, 430);
    //container.setUndecorated(true);
    container.setLocationRelativeTo(null);
    setSize(WorldMap.MAP_WIDTH, WorldMap.MAP_HEIGHT);

    // setup our canvas size and put it into the content of the frame
    setBounds(0, 0, WorldMap.MAP_WIDTH, WorldMap.MAP_HEIGHT);
    //setLocation(0, 30);
    //setLocation(0, 10);

    //panel.add(this);
    container.add(this);

    // Tell AWT not to bother repainting our canvas since we're
    // going to do that our self in accelerated mode
    setIgnoreRepaint(true);

    // finally make the window visible 
    //container.pack();

    //container.setResizable(false);
    container.setVisible(true);

    // add a listener to respond to the user closing the window. If they
    // do we'd like to exit the game
    /*container.addWindowListener(new WindowAdapter()
    {
      @Override public void windowClosing(final WindowEvent e)
      {
        System.exit(0);
      }
    });*/
    container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // add a key input system (defined below) to our canvas
    // so we can respond to key pressed
    addKeyListener(new KeyInputHandler(this));

    // request the focus so key events come to us
    requestFocus();

    // create the buffering strategy which will allow AWT
    // to manage our accelerated graphics
    createBufferStrategy(2);
    strategy = getBufferStrategy();

    map = new WorldMap(this, "/maps/level-0-2.map");
    //map.initMap();
    map.initMapView(0, 0);

    player = new PlayerEntity(this, "sprites/hero.png", 80, 80);
    getEntities().add(player);
  }

  public void gameLoop()
  {
    while (gameRunning)
    {
      final Graphics2D g = (Graphics2D)strategy.getDrawGraphics();
      //g.setColor(Color.RED);
      //g.fillRect((int)panel.getBounds().getX(), (int)panel.getBounds().getY(), 400, 400);

      for (int i = 0; i < getEntities().size(); i++)
      {
        final Entity entity = getEntities().get(i);
        entity.move();
        entity.draw(g);

      }

      //player.draw(g);
      /*for (int i = 0; i < getEntities().size(); i++)
      {
        final Entity entity = getEntities().get(i);
        entity.draw(g);

      }*/

      g.dispose();
      //this.update(g);
      strategy.show();

      player.setHorizontalMovement(0);
      player.setVerticalMovement(0);
      //System.out.println(this.getLocation().getX() + " , " + this.getLocation().getY());
      if ((leftPressed) && (!rightPressed))
      {
        //player.setSprite(SpriteStore.get().getSprite("sprites/ship.gif"));
        player.setHorizontalMovement(-player.getMovespeed());
        for (int i = 0; i < entities.size(); i++)
        {
          final Entity entity = entities.get(i);

          if (entity instanceof WallEntity)
          {
            if (player.CanCollidesWith(entity))
            {
              player.setHorizontalMovement(0);
            }
          }
          if (this.getBounds().getX() < 0)
          {
            if (player.getX() < (-this.getBounds().getX() + 120))
            {
              final PlayerEntity playerTmp = (PlayerEntity)getEntities().get(getEntities().indexOf(player));
              this.setBounds((int)(this.getBounds().getX() + 4), (int)(this.getBounds().getY()), WorldMap.MAP_WIDTH, WorldMap.MAP_HEIGHT);
              //this.setLocation((int)(this.getLocation().getX() + 4), (int)(this.getLocation().getY()));
              if ((this.getLocation().getX() % 40) == 0)
              {
                //System.out.println(this.getLocation().getX() / 40);
                //map.initMapView(Math.abs((int)this.getLocation().getX() / 40), Math.abs((int)this.getLocation().getY() / 40));
                map.initMapView(Math.abs((int)this.getBounds().getX() / 40), Math.abs((int)this.getBounds().getY() / 40));
                getEntities().remove(player);
                getEntities().add(playerTmp);

              }
            }
          }
        }
      }
      else if ((rightPressed) && (!leftPressed))
      {
        player.setHorizontalMovement(player.getMovespeed());
        for (int i = 0; i < entities.size(); i++)
        {
          final Entity entity = entities.get(i);

          if (entity instanceof WallEntity)
          {
            if (player.CanCollidesWith(entity))
            {
              player.setHorizontalMovement(0);
            }
          }
        }

        if (this.getBounds().getX() > -WorldMap.MAP_WIDTH + (WorldMap.TILD_WIDTH * WorldMap.NB_TILD_ON_SCREEN))
        {
          if (player.getX() > (-this.getBounds().getX() + (WorldMap.TILD_WIDTH * WorldMap.NB_TILD_ON_SCREEN - 160)))
          {
            final PlayerEntity playerTmp = (PlayerEntity)getEntities().get(getEntities().indexOf(player));
            //this.setBounds((int)(this.getBounds().getX() - 4), (int)(this.getBounds().getY()), WorldMap.MAP_WIDTH, WorldMap.MAP_HEIGHT);
            this.setLocation((int)(this.getLocation().getX() - 4), (int)(this.getLocation().getY()));
            if ((this.getLocation().getX() % 40) == 0)
            {
              System.out.println(this.getLocation().getX() / 40);
              //map.initMapView(Math.abs((int)this.getLocation().getX() / 40), Math.abs((int)this.getLocation().getY() / 40));
              map.initMapView(Math.abs((int)this.getBounds().getX() / 40), Math.abs((int)this.getBounds().getY() / 40));
              getEntities().remove(player);
              getEntities().add(playerTmp);

            }
          }
        }
      }
      if ((upPressed) && (!downPressed))
      {
        player.setVerticalMovement(-player.getMovespeed());
        for (int i = 0; i < entities.size(); i++)
        {
          final Entity entity = entities.get(i);

          if (entity instanceof WallEntity)
          {
            if (player.CanCollidesWith(entity))
            {
              player.setVerticalMovement(0);
            }
          }
        }
        if (this.getBounds().getY() < 0)
        {
          if (player.getY() < (-this.getBounds().getY() + 120))
          {
            final PlayerEntity playerTmp = (PlayerEntity)getEntities().get(getEntities().indexOf(player));
            //this.setBounds((int)(this.getBounds().getX()), (int)(this.getBounds().getY() + 4), WorldMap.MAP_WIDTH, WorldMap.MAP_HEIGHT);
            this.setLocation((int)(this.getLocation().getX()), (int)(this.getLocation().getY() + 4));
            if ((this.getLocation().getY() % 40) == 0)
            {
              //System.out.println(this.getLocation().getY() / 40);
              //map.initMapView(Math.abs((int)this.getLocation().getX() / 40), Math.abs((int)this.getLocation().getY() / 40));
              map.initMapView(Math.abs((int)this.getBounds().getX() / 40), Math.abs((int)this.getBounds().getY() / 40));
              getEntities().remove(player);
              getEntities().add(playerTmp);

            }
          }
        }
      }
      else if ((downPressed) && (!upPressed))
      {
        player.setVerticalMovement(player.getMovespeed());
        for (int i = 0; i < entities.size(); i++)
        {
          final Entity entity = entities.get(i);

          if (entity instanceof WallEntity)
          {
            if (player.CanCollidesWith(entity))
            {
              player.setVerticalMovement(0);
            }
          }
        }
        if ((this.getBounds().getY() > -WorldMap.MAP_WIDTH + (WorldMap.TILD_WIDTH * WorldMap.NB_TILD_ON_SCREEN)))
        {
          if (player.getY() > (-this.getBounds().getY() + (WorldMap.TILD_WIDTH * WorldMap.NB_TILD_ON_SCREEN - 160)))
          {
            final PlayerEntity playerTmp = (PlayerEntity)getEntities().get(getEntities().indexOf(player));
            //this.setBounds((int)(this.getBounds().getX()), (int)(this.getBounds().getY() - 4), WorldMap.MAP_WIDTH, WorldMap.MAP_HEIGHT);
            this.setLocation((int)(this.getLocation().getX()), (int)(this.getLocation().getY() - 4));
            //System.out.println(this.getLocation().getY() / 40);
            if ((this.getLocation().getY() % 40) == 0)
            {
              System.out.println(this.getLocation().getY() / 40);
              //map.initMapView(Math.abs((int)this.getLocation().getX() / 40), Math.abs((int)this.getLocation().getY() / 40));
              map.initMapView(Math.abs((int)this.getBounds().getX() / 40), Math.abs((int)this.getBounds().getY() / 40));
              getEntities().remove(player);
              getEntities().add(playerTmp);

            }
          }

        }

      }

      try
      {
        Thread.sleep(10);
      }
      catch (final Exception e)
      {
      }
    }
  }

  private class KeyInputHandler extends KeyAdapter
  {

    @SuppressWarnings("unused") private final Game game;

    public KeyInputHandler(final Game game)
    {
      this.game = game;
    }

    @Override public void keyPressed(final KeyEvent e)
    {
      if (e.getKeyCode() == KeyEvent.VK_LEFT)
      {
        leftPressed = true;
      }
      if (e.getKeyCode() == KeyEvent.VK_RIGHT)
      {
        rightPressed = true;
      }
      if (e.getKeyCode() == KeyEvent.VK_UP)
      {
        upPressed = true;
      }
      if (e.getKeyCode() == KeyEvent.VK_DOWN)
      {
        downPressed = true;
      }
      if (e.getKeyCode() == KeyEvent.VK_A)
      {
        System.out.println("ok");
      }
    }

    @Override public void keyReleased(final KeyEvent e)
    {
      if (e.getKeyCode() == KeyEvent.VK_LEFT)
      {
        leftPressed = false;
      }
      if (e.getKeyCode() == KeyEvent.VK_RIGHT)
      {
        rightPressed = false;
      }
      if (e.getKeyCode() == KeyEvent.VK_UP)
      {
        upPressed = false;
      }
      if (e.getKeyCode() == KeyEvent.VK_DOWN)
      {
        downPressed = false;
      }
    }

    @Override public void keyTyped(final KeyEvent e)
    {

      // if we hit escape, then quit the game
      if (e.getKeyChar() == 27)
      {
        System.exit(0);
      }
    }
  }

  public static void main(final String argv[])
  {
    final Game g = new Game();
    g.gameLoop();
  }

  /**
   * @return the entities
   */
  public ArrayList<Entity> getEntities()
  {
    return entities;
  }
}
